#include "StdAfx.h"
#include "AddIn.h"
#include "SolutionEventHandler.h"

SolutionEventHandler::SolutionEventHandler(void)
{
}

SolutionEventHandler::~SolutionEventHandler(void)
{
	UnAdvise();
}

BOOL SolutionEventHandler::Advise(EnvDTE80::DTE2 *pDTE, ISolutionEventHandler *pReceiver)
{
	UnAdvise();

	BOOL bRet = FALSE;

	if ((pDTE) && (pReceiver))
	{
		m_pReceiver = pReceiver;

		EnvDTE::EventsPtr spEvents;
		EnvDTE::_SolutionEventsPtr sp_SolutionEvents;
		IConnectionPointContainerPtr spCon;
		
		if (SUCCEEDED(pDTE->get_Events(&spEvents)) &&
			SUCCEEDED(spEvents->get_SolutionEvents(&sp_SolutionEvents)) &&
			(spCon = sp_SolutionEvents) &&
			SUCCEEDED(spCon->FindConnectionPoint(EnvDTE::DIID__dispSolutionEvents, &m_spCP)) &&
			SUCCEEDED(m_spCP->Advise(this, &m_dwCookie)))
			bRet = TRUE;
	}

	return bRet;
}

void SolutionEventHandler::UnAdvise()
{
	if (m_spCP)
	{
		m_spCP->Unadvise(m_dwCookie);
		m_spCP = NULL;
	}

	m_pReceiver = NULL;
}

HRESULT STDMETHODCALLTYPE SolutionEventHandler::QueryInterface(REFIID riid, void** ppvObject)
{
	if (ppvObject == NULL)
		return E_POINTER;

	if ((riid == IID_IUnknown) ||
		(riid == IID_IDispatch) ||
		(riid == EnvDTE::DIID__dispSolutionEvents))
	{
		*ppvObject = this;
		//AddRef();
		return S_OK;
	}

	return E_NOINTERFACE;
}

ULONG STDMETHODCALLTYPE SolutionEventHandler::AddRef(void)
{
	return 1;
}

ULONG STDMETHODCALLTYPE SolutionEventHandler::Release(void)
{
	return 1;
}

HRESULT STDMETHODCALLTYPE SolutionEventHandler::GetTypeInfoCount(UINT *pctinfo)
{
	return E_NOTIMPL;
}

HRESULT STDMETHODCALLTYPE SolutionEventHandler::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
{
	return E_NOTIMPL;
}

HRESULT STDMETHODCALLTYPE SolutionEventHandler::GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
{
	return E_NOTIMPL;
}

HRESULT STDMETHODCALLTYPE SolutionEventHandler::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
{
	switch(dispIdMember)
	{
	case 1:
		m_pReceiver->Opened();
		break;
	case 2:
		m_pReceiver->BeforeClosing();
		break;
	case 3:
		m_pReceiver->AfterClosing();
		break;
	case 4:
		m_pReceiver->QueryCloseSolution(pDispParams->rgvarg[0].pboolVal);
		break;
	case 5:
		m_pReceiver->Renamed(pDispParams->rgvarg[0].bstrVal);
		break;
	case 6:
		{
			EnvDTE::ProjectPtr spProject = pDispParams->rgvarg[0].pdispVal;
			m_pReceiver->ProjectAdded(spProject);
		}
		break;
	case 7:
		{
			EnvDTE::ProjectPtr spProject = pDispParams->rgvarg[0].pdispVal;
			m_pReceiver->ProjectRemoved(spProject);
		}
		break;
	case 8:
		{
			EnvDTE::ProjectPtr spProject = pDispParams->rgvarg[1].pdispVal;
			m_pReceiver->ProjectRenamed(spProject, pDispParams->rgvarg[0].bstrVal);
		}
		break;
	}


	return S_OK;
}
